const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// css文件压缩处理
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')

module.exports = {
  target: "web",
  entry: {
    main:'./src/js/index.js',
    print:'./src/js/print.js'
  },
  output: {
    filename: 'js/[name].[contenthash:5].js',
    path: resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      // loader的配置
      {
        // 处理css资源
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            // 还需要在package.json中定义browserslist
            loader: 'postcss-loader',
            options: {
              'postcssOptions':{
                plugins:['postcss-preset-env']
              }
            }
          }
        ]
      },
      {
        test: /\.js$/,
        include: [
          resolve(__dirname, './src')
        ],
        loader: 'babel-loader',
        options: {
          // 预设：指示babel做怎么样的兼容性处理
          presets: [
            [
              '@babel/preset-env',
              {
                // 按需加载
                useBuiltIns: 'usage',
                // 指定core-js版本
                corejs: {
                  version: 3
                },
                // 指定兼容性做到哪个版本浏览器
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ],
          // 开启babel缓存
          // 第二次构建时，会读取之前的缓存
          // cacheDirectory: true
        }
      },
      {
        // 处理html中img资源
        test: /\.html$/,
        loader: 'html-loader'
      },
    ]
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename:'css/[name].[contenthash:5].css'
    }),
    // css压缩
    new CssMinimizerWebpackPlugin()
  ],
  mode: 'production',
  /*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中，有没有公共的文件。如果有会打包成单独一个chunk
  */
  optimization: {
    splitChunks: {
      // chunks 可以设置的值有三个
      // 1. async 对异步(async)引入的包进行分包操作 默认值
      // 2. inital 对同步引入的包进行分包操作
      // 3. all 对所有引入的包全部进行分包操作
      chunks: 'all'
    }
  },
  /**
   * splitChunks 详解
   *    optimization: {
          splitChunks: {
            chunks: 'all',
            // 默认值是20000Byte，表示大于这个大小的引入文件都需要抽离出来
            minSize: 20000,
            // 表示的是大于多少字节的包需要进行二次拆分，拆分为不小于minSize的包
            // 多数情况下，如果设置maxSize的值的时候，minSize和maxSize的值一般是一致的
            maxSize: 20000,
            // 某一个包引入了多少次就需要被抽离出来
            minChunks: 1,

            // cacheGroups的含义是 所有的模块输出，会存放在缓存中，最后一起执行对应的操作
            // 在这个属性里面可以自己自定义的代码分割配置
            // cacheGroups的优先级小于minSize和maxSize，所以当两种冲突的时候，cacheGroup中的配置会默认失效
            cacheGroups: {
              // key可以任意取，在这边只是一个占位符
              // value是一个配置对象
              vendor: {
                // 正则，用以匹配对应的模块路径
                test: /[\\/]node_modules[\\/]/,
                // 输出文件名 输出文件会以 输出文件名-hash值.js的形式输出
                // name: "vender",
                
                // filename 输出文件名，和name不同的是，filename中可以使用placeholder
                filename: 'vendor_[id].js',
                // 优先级 在这个配置中约定俗称，一般设置为负数
                priority: -10
              },
              default: {
                minChunks: 2,
                filename: "common_[id].js",
                priority: -20
              }
            }
          }
        }

        文件名说明
        main.bundle.js主代码文件
        runtime.bundle.js webpack的辅助函数抽取文件
        vendor.bundle.js所有第三方包所在的文件
        common.bundle.js如果存在多入口的时候，所有重复引入的模块，当引用次数超过一定次数的时候时候，会抽取到的一个文件
   */
  devServer: {
    compress: true,
    port: 3000,
    open: true,
    // 开启HMR功能
    // 当修改了webpack配置，新配置要想生效，必须重新webpack服务
    hot: true
  },
  devtool: 'source-map'
};